#if !defined(glib_operations_h)
#define glib_operations_h

#include <cmath>

//doubles a value

template <class T>
inline T dbl(T v)
	{ return 2 * v; }

template <>
inline float dbl(float v)
	{ return 2.0f * v; }

template <>
inline double dbl(double v)
	{ return 2.0 * v; }

//halves a value

template <class T>
inline T half(T v)
	{ return v / 2; }

template <>
inline float half(float v)
	{ return 0.5f * v; }

template <>
inline double half(double v)
	{ return 0.5 * v; }

//divides a value by 4

template <class T>
inline T quarter(T v)
	{ return v / 4; }

template <>
inline float quarter(float v)
	{ return 0.25f * v; }

template <>
inline double quarter(double v)
	{ return 0.25 * v; }

//divides a value by 8

template <class T>
inline T octant(T v)
	{ return v / 8; }

template <>
inline float octant(float v)
	{ return 0.125f * v; }

template <>
inline double octant(double v)
	{ return 0.125 * v; }

//reises a value to the second power

template <class T>
class squarer {
	T s;
public:
	explicit squarer(const T & v) : s(v * v) { }
	operator T () const { return s; }
};

template <class T>
inline squarer<T> sqr(const T & v)
	{ return squarer<T>(v); }

//gets absolute value

template <class T> ///< for int types only
class absoluter {
	T a;
public:
	explicit absoluter(const T & v) : a(std::abs(v)) { }
	operator T () const { return a; }
};

template <>
class absoluter<float> {
	float a;
public:
	explicit absoluter(const float & v) : a(std::fabs(v)) { }
	operator float () const { return a; }
};

template <>
class absoluter<double> {
	double a;
public:
	explicit absoluter(const double & v) : a(std::fabs(v)) { }
	operator double () const { return a; }
};

template <class T>
inline absoluter<T> absolute(const T & v)
	{ return absoluter<T>(v); }

#endif // glib_operations_h